AlteryxでRツールを使わずに線形回帰を実装する
こんにちは、小澤です。
Alteryxには様々なツールが用意されていますが、 それでも性質上RツールやPythonツールを使ってコードを書いてしまった方が自由度は高くなります。
が、しかし!それではいけません! 最近はRツール関連の記事を書くことも多かったですが、ここいらで一発それらのツール禁止縛りをしたいと思います。
テーマは「線形回帰の実装」です。 AlteryxにはLinear Regressionツールというそれを実現するためのツールがすでに存在していますが、内部的にはRツールを使っています。 そこで、Rツールを使わずに実装してみましょう。 今回は内容をシンプルにするため、切片なしの単回帰のみを扱うワークフローを作成します。
線形回帰ってどんなことするの?
線形回帰は「ある値」から「別なある値」を直線で当てはめて予測するものです。 以下のグラフの縦軸の値を横軸の値から予測するとします。
これに対して、以下のような直線の値を予測値として求めます。
これは実際の値として、横軸が「気温」、縦軸が「ビールの売上」のような数値となります。
この直線をどのように求めるかはワークフローを作成していく中で解説します。
ワークフローを作成する
さて、では今回作成するワークフローを見ていきましょう。
あれ?とってもシンプルですね... 実はこれ、マクロを使ってるんで実際の処理はほとんど見えていません。
マクロの中身を確認する前に、このワークフローの内容を簡単に確認しておきます。
入力データは以下のようになっています。
先ほどのグラフのそれぞれの軸に対応した値となっています。 その次のSelectツールは、2つとも列の型を実数にしています。
続いての絵が描かれていない茶色いアイコンがいよいよマクロです。 この中身を見ていきましょう。
マクロの中身
マクロの全体像は以下のようになっています。
最初のワークフローで油断させておいてのこれですw
さて、このマクロを解説するために線形回帰の基本を説明しておきます。 今回は単純化のため、切片なしの単回帰としているため、入力データのxからyの値は以下のような計算で求められるものとしています。
[latex] y = ax [/latex]
いきなり数式が出てきてブラウザバックを押そうとして方もいるかもしれませんが、ちょっと待ってください。 これは、一次関数の式となっており観測されたxに何らかの値を掛けることでyの値が予測できると想定したものになります。 例えば、気温とビールの例であれば気温に何ならかの値を掛けることでビールの売上が計算できるといった仕組みです。 そして、一次関数なのでxとyの関係は直線で表される、という冒頭のグラフの直線を求める式になっています。 xとyの値はデータとして複数個与えられているので、あとはaをどういう値にするかをこのワークフローで決定します。
このaをまずはランダムな値で作成します。 ランダムな値を生成するのに、Formulaツールを使っていますが、Formulaツールはインプットが必須なので、ダミーの値を生成したのち、Formulaツールにてwという列名で乱数を作成しています。
RAND()
結果は以下のようになりますが、乱数なので実行するたびに値は異なる点にご注意ください。
この係数が適切な値であれば、xを与えたときに適切なyを予測できることになります。 この段階ではまだランダムな値を入れているので予測値も残念な結果となるでしょう。
続いて、yの予測値を求めるにはx * wの計算を行う必要があるため、Append Fieldツールを使って入力データの全ての行にwの値を付与しています。
続いては、またまた絵の描いていない茶色いアイコンが出てきました。 なんと、こちらもさらにマクロです!
マクロの中のマクロのワークフロー
では、さらにこの中のマクロの処理を確認していきましょう。 こちらの全体像は以下のようになっています。
「お、こっちはそんな複雑じゃないぞ!」と思った方は残念! このマクロはみんな大好きIterativeマクロです!! マクロの中にさらにマクロを入れていた理由はIterativeマクロが必要だったからなんです。 どのようにループするのかは後回しとして、まずは処理の流れを見てみましょう。
最初のFormulaツールでは以下のような処理を行って、「e_i」という列を作成しています。
([y] - [x] * [w]) * [x]
なんの計算をしているかいきなり意味が分かりませんねw これは、現在のwの値でどれだけうまくyの値の予測ができているかを求める計算の一部です。 一部なので、計算を全部済ませてから何をしてたのか確認しましょう。
続いてのSummarizeツールでは以下のような設定をしています。
先ほどのFormulaツールで求めたe_iの合計値とデータ件数を取得しています。
その次のFormulaツールでこの部分の計算の最後になります。 以下のような計算をして、「e」という列を作成しています。
-([Sum_e_i] / [Count])
さて、ここまでで一通りの計算が終わりましたが、何をしてるのかわからなかったと思います。 これは、以下のような手順のうち1と2のための準備を行っています。
- 現在のwの値で正しいyからどのくらい外れているかを計算する
- より良いwになるように値を更新する
1の手順では、どのくらい外れているかの指標を以下の式で求めます。
[latex] E = \frac{1}{2N} \sum_{i=1}^{N} (y_i - wx_i)^2 [/latex]
雰囲気的には現在のwの値で計算した結果と正しいyの値の差の平均をとっている感じだと思ってください。Nはデータの件数です。 この値を小さくすればいい感じの結果となるわけですが、それをするためにwで微分した値を求めます(とりあえずそういうものだと思ってください)。
[latex] \frac{dE}{dw} = -\frac{1}{N} \sum_{i=1}^{N} (y_i - wx_i)x_i [/latex]
この計算のΣの中身を最初のFormulaツール、Σの計算をSummarizeツール、Nで割る計算を2つ目のFormulaツールで行っていたわけです。
なお、よくわからなくても「ふーん、そうやって計算するだ」くらいの理解でも問題ありません。
続いての処理では、ここで計算した値を使ってwを更新します。 wと同様Append Fieldsツールでeの値をすべてのデータに持たせています。 その後Formulaツールで以下の計算を行ってwの値を書き換えています。
[w] - [#1] * [e]
「#1」はNumeric Up Downツールから受け取る値となっています。 これは、更新する値をどのくらい効かせるかの係数となっています。 重要な値ではあるのですがとりあえず、「係数を入れてるんだな」、くらいの認識でいいでしょう。
これでwの値が初期値よりちょっとだけいい結果になるように更新されました。 あとは、この計算を繰り返していけばどんどんwの値が書き換わっていって、いい感じの予測値を出せるようになっていきます。 この「計算をどんどん繰り返す」ためにIterativeマクロを使っていたのです。
最後のFilterツールでは、eの値が一定以上かを確認しています。 eの値を0に近づけていくことが目的(微分した結果を0にすることでyと予測値の差を小さくしていくことができるけど、この部分はも「そうなんだ」理解でokです)なので、閾値を決めておいて一定以下になったらそこでループを終了させるため下側に出力され、まだwの更新が必要な場合は上側に出力されるようになっています。
Iterativeマクロはループ回数の上限を設定する必要があるため、これでいい感じのwとなるか一定回数以上ループしたらこのマクロは終了します。 そして、その出力はいい感じのwを含むデータとなっています。
そして最初のマクロに戻る
さて、Iterativeマクロでいい感じのwが得られたので、これで無事線形回帰ができました! めでたしめでたし! と思った、そこのあなた、Iterativeマクロに入る前のマクロにまだ続きがあったのを覚えていますか?
というかほとんどの部分を解説していませんね。 wが求まったのに何でまだ処理があるの?と思われた方、その通りなんですが、ここから先はどのくらいいい感じのwになっているのかを評価しています。
まず、最初はIterativeマクロ終了時にループ上限に達したのか、eの値が一定以下になったのかわからないため、2つの結果をUnionツールで結合しています。 出力は常にどちらか一方のみなので「どっちに出力されても大丈夫」な状態を作っています。
その後、上側ではwの値を出力しています。 wは各データの列として入っているので、Selectツールでwのみ選択、Uniqueツールで1件のデータにするという処理をしています。
問題は下側が複雑です。。 この部分は3つのパーツに分かれています。
上側はxとyの値に回帰線を引いた冒頭2枚目のグラフを生成しています。 これはInteractive Chartツールでxとyの値の散布図と、xと予測値の値の折れ線グラフを重ねたものとなります。
真ん中は、RMSEという「予測値が平均してどのくらいyの値と誤差があるのか」を計算しています。 以下のような計算を行う処理になっています。
[latex] RMSE = \sqrt{\frac{\sum_{i=1}^{N}(y_i - \hat{y}_i)^2}{N}} [/latex]
式中の\(\hat{y}\)は予測値です。
下側は決定係数という0-1の範囲の値で1に近いほどいい感じに予測値が当てはまってる指標になります。 以下の式で計算できます。
[latex] R^2 = 1 - \frac{\sum_{i=1}^{N}(y_i - \hat{y}_i)^2}{\sum_{i=1}^{N}(y_i - \bar{y}_i)^2} [/latex]
式中の\(\bar{y}\)はyの平均値です。
このあたりの実装の詳細は割愛しますので、「そんなこともしてるんだなー」くらいの感じとらえておいてください。
最後にこれらをまとめてレポートにしたものを出力しています。 出力は以下の2つになります。
- wの値
- レポート
おわりに
今回は、Rツールを使わずに線形単回帰を行うワークフローを実装しました。 これ自体に実用性があるかと言われるとそうでもないです。 ものすごく頑張れば、この仕組みを拡張して(速度などの実用性はともかくとして)Deep LearningをRツールやPythonツールを使わずに実現することもたぶん可能です。
また、本記事のワークフローに関しましては弊社ご契約のユーザ様は、専用ポータルからダウンロードできます。
Alteryxの導入なら、クラスメソッドにおまかせください
日本初のAlteryxビジネスパートナーであるクラスメソッドが、Alteryxの導入から活用方法までサポートします。14日間の無料トライアルも実施中ですので、お気軽にご相談ください。